package ru.vsu.amm.input;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author Малютин Евгений
 * 
 */
public class Input {
	
	private static final String PARAMETERS_PREFIX = "Parameters";
	private static final String BOUNDARY_CONDITIONS_PREFIX = "BoundaryConditions";
	private static final String FILES_EXTENSION = "txt";
	private static final String FILENAME_PUTTERN = "data/%s%s.%s";
	
	private static final boolean LOG = true;
	private static final boolean DEBUG = false;
	
	public double hx,hy,hz;
	public int Nx,Ny,Nz;
	public double E, nu;
	public List<Object[]> boundaryConditions;
	
	private boolean isValid; 
	
	public Input(int testNumber) {
		this(testNumber, true);
	}
	
	public Input(int testNumber, boolean readBoundaryConditions) {
		if (!readParameters(testNumber))
			return;
		
		if (readBoundaryConditions && !readBoundaryConditions(testNumber))
			return;
		
		isValid = true;
	}
	
	public boolean isValid() {
		return isValid;
	}
	
	private boolean readParameters(int testNumber) {
		String parametersFileName = generateParametersFileName(testNumber);
		try (BufferedReader inP = new BufferedReader(new FileReader(parametersFileName))) {
			 String[] line;
			 
			 line = inP.readLine().trim().split(" "); 
			 hx = Double.parseDouble( line[ 0 ] );
			 hy = Double.parseDouble( line[ 1 ] );
			 hz = Double.parseDouble( line[ 2 ] );
			 
			 line = inP.readLine().trim().split(" "); 
			 Nx = Integer.parseInt(line[0]);
			 Ny = Integer.parseInt(line[1]);
			 Nz = Integer.parseInt(line[2]);
			 
			 line = inP.readLine().trim().split(" ");
			 E = Double.parseDouble( line[ 0 ] );
			 nu = Double.parseDouble( line[ 1 ] );
			 
			 if (LOG) {
				 System.out.println("    <hx, hy, hz>\t"+hx+"\t"+hy+"\t"+hz);
				 System.out.println("    <Nx, Ny, Nz>\t"+Nx+"\t"+Ny+"\t "+Nz);
				 System.out.println("         <E, nu>\t"+E+"\t"+nu);
			 }
		} catch (Exception e) {
			System.err.println("File "+parametersFileName+" is not found or cannot be read properly");
			return false;
		}
		
		return true;
	}
	
	private boolean readBoundaryConditions(int testNumber) {
		String boundaryConditionsFileName = generateBoundaryConditionsFileName(testNumber);
		try (BufferedReader inBC = new BufferedReader(new FileReader(boundaryConditionsFileName))) {
			boundaryConditions = new ArrayList<Object[]>();
			
			String line;
			while ((line = inBC.readLine()) != null)
				try {
					String[] sCondition = line.trim().split(" ");
					if (sCondition.length < 4)
						continue;
					
					Object[] condition = new Object[4];
					
					condition[0] = Integer.parseInt(sCondition[0]);
					for (int i = 1; i < sCondition.length; i++)
						condition[i] = Double.parseDouble(sCondition[i]);
					
					boundaryConditions.add(condition);
					
					if (LOG) {
						System.out.print(" <boundary cond>\n");
						System.out.print("             <n>\t"+condition[0]+"\n");
						System.out.print("    <u, v, w>\t"+condition[1]+"\t"+condition[2]+"\t"+condition[3]+"\n");
					}
				} catch(Exception e) {}
			
			if (DEBUG) {
				for (int i = 0; i < boundaryConditions.size(); i++) {
					for (int j = 0; j < 4; j++) {
						System.out.print(boundaryConditions.get(i)[j]+" ");
					}
					System.out.println();
				}
			}
		} catch (Exception e) {
			System.err.println("File "+boundaryConditionsFileName+" is not found or cannot be read properly");
			return false;
		}
		
		return true;
	}
	
	private static String getFileName(String prefix, int testNumber, String extension) {
		return String.format(FILENAME_PUTTERN, prefix, testNumber, extension);
	}
	
	public static String generateParametersFileName(int testNumber) {
		return getFileName(PARAMETERS_PREFIX, testNumber, FILES_EXTENSION);
	}
	
	public static String generateBoundaryConditionsFileName(int testNumber) {
		return getFileName(BOUNDARY_CONDITIONS_PREFIX, testNumber, FILES_EXTENSION);
	}
}